package main

import (
	"fmt"
	"os"
	codecs "sanguo/codec/cs"
	"sanguo/node/client/dispatcher"
	"sanguo/node/client/login"
	cs_msg "sanguo/protocol/cs/message"
	"strconv"
	"time"

	"github.com/golang/protobuf/proto"
	"github.com/sniperHW/kendynet"
)

var userNum_ int = 0

var createfail, createok int = 0, 0
var createTime int64 = 0

var roleListfail, roleListok int = 0, 0
var roleListTime int64 = 0

var selectfail, selectok int = 0, 0
var selectTime int64 = 0

var enterMapfail, enterMaptok int = 0, 0
var enterMapTime int64 = 0

var num int = 0

func main() {
	//	if len(os.Args) < 3 {
	//		fmt.Printf("usage selectRole userID addr\n")
	//		return
	//	}

	Num := os.Args[1]
	//str := os.Args[2]
	addr := "10.128.2.153:9010"
	userNum, _ := strconv.Atoi(Num)
	userNum_ = userNum

	for userID := 1000; userID < userNum+1000; userID++ {
		Name := fmt.Sprintf("%d", userID)
		login.Login(Name, addr, func(session kendynet.StreamSession, d *dispatcher.Dispatcher, msg *codecs.Message, err error) {
			if nil != err {
				fmt.Println(err)
			} else {
				var createTime1, roleListTime1, selectTime1, enterMapTime1 int64

				gameLoginToC := msg.GetData().(*cs_msg.GameLoginToC)
				if gameLoginToC.GetCode() == cs_msg.EnumType_OK {
					num += 1
					//createRole(session, Name)
					roleList(session)
					createTime1 = time.Now().UnixNano() / 1e6
				}

				d.Register(&cs_msg.CreateRoleToC{}, false, func(args []interface{}) {
					resp := args[1].(*codecs.Message).GetData().(*cs_msg.CreateRoleToC)
					fmt.Println("CreateRoleToc", resp)
					createTime += time.Now().UnixNano()/1e6 - createTime1
					if resp.GetErrcode() == cs_msg.EnumType_ERROR {
						createfail += 1
					} else if resp.GetErrcode() == cs_msg.EnumType_OK {
						createok += 1
						roleListTime1 = time.Now().UnixNano() / 1e6
						roleList(session)
					}

				})
				d.Register(&cs_msg.RoleListToC{}, false, func(args []interface{}) {
					resp := args[1].(*codecs.Message).GetData().(*cs_msg.RoleListToC)
					roleListTime += time.Now().UnixNano()/1e6 - roleListTime1
					if resp.GetErrcode() == cs_msg.EnumType_ERROR {
						roleListfail += 1
					} else if resp.GetErrcode() == cs_msg.EnumType_OK {
						roleListok += 1
						selectTime1 = time.Now().UnixNano() / 1e6
						selectRole(session, resp)
					}
				})

				d.Register(&cs_msg.SelectRoleToC{}, false, func(args []interface{}) {
					resp := args[1].(*codecs.Message).GetData().(*cs_msg.SelectRoleToC)
					selectTime += time.Now().UnixNano()/1e6 - selectTime1
					if resp.GetErrcode() == cs_msg.EnumType_ERROR {
						selectfail += 1
					} else if resp.GetErrcode() == cs_msg.EnumType_OK {
						selectok += 1
						enterMapTime1 = time.Now().UnixNano() / 1e6
						enterMap(session)
					}
					//endrole()
				})

				d.Register(&cs_msg.EnterMapToC{}, false, func(args []interface{}) {
					resp := args[1].(*codecs.Message).GetData().(*cs_msg.EnterMapToC)
					enterMapTime += time.Now().UnixNano()/1e6 - enterMapTime1
					if resp.GetErrcode() == cs_msg.EnumType_OK {
						//req2 := &cs_msg.StartAoiToS{}
						//session.Send(codecs.NewMessage(uint16(0), req2))
						updatePos(session, resp.GetPos().GetX(), resp.GetPos().GetY(), resp.GetPos().GetZ(), resp.GetAngle())
					}
				})

				d.Register(&cs_msg.StartAoiToC{}, true, func(args []interface{}) {
					resp := args[1].(*codecs.Message).GetData().(*cs_msg.StartAoiToC)
					fmt.Println("StartAoiToC", resp)
				})

				d.Register(&cs_msg.EnterSeeToC{}, false, func(args []interface{}) {
					fmt.Println("onEnterSee")
					resp := args[1].(*codecs.Message).GetData().(*cs_msg.EnterSeeToC)
					fmt.Println(resp)
				})

				d.Register(&cs_msg.UpdatePosToC{}, false, func(args []interface{}) {
					resp := args[1].(*codecs.Message).GetData().(*cs_msg.UpdatePosToC)
					kendynet.Infoln("read", resp)
				})

			}
		})
	}

	sigStop := make(chan bool)
	_, _ = <-sigStop
}

func createRole(session kendynet.StreamSession, name string) {
	req := &cs_msg.CreateRoleToS{
		Face:      proto.Int32(14011),
		Hair:      proto.Int32(14021),
		HairColor: proto.Int32(0),
		EyeColor:  proto.Int32(14031),
		Cloth:     proto.Int32(14051),
		Outline:   proto.Int32(10001),
		Name:      proto.String(name),
		Portrait:  proto.Int32(100001),
	}

	session.Send(codecs.NewMessage(uint16(0), req))

}

func roleList(session kendynet.StreamSession) {
	req := &cs_msg.RoleListToS{}
	session.Send(codecs.NewMessage(uint16(0), req))
}

func selectRole(session kendynet.StreamSession, resp *cs_msg.RoleListToC) {
	var roleIDMap map[int]uint64 = make(map[int]uint64)
	for k, v := range resp.RoleList {
		roleIDMap[k] = v.GetID()
	}
	req2 := &cs_msg.SelectRoleToS{
		ID: proto.Uint64(roleIDMap[0]),
	}
	session.Send(codecs.NewMessage(uint16(0), req2))
}

func enterMap(session kendynet.StreamSession) {
	req := &cs_msg.EnterMapToS{}
	session.Send(codecs.NewMessage(uint16(0), req))
}

func updatePos(session kendynet.StreamSession, x, y, z, angle int32) {
	go func() {
		for {
			time.Sleep(time.Millisecond * 500)
			x += 100
			z += 100
			y = 12300
			angle += 100
			if x > 18000 {
				x = 12000
			}
			if z > 19000 {
				z = 14000
			}

			if angle > 360 {
				angle = 0
			}
			pos := &cs_msg.Position{
				X: proto.Int32(x),
				Y: proto.Int32(y),
				Z: proto.Int32(z),
			}
			req := &cs_msg.MoveToS{}
			req.Pos = pos
			req.Angle = proto.Int32(angle)
			fmt.Println("send", req)
			session.Send(codecs.NewMessage(uint16(0), req))
		}
	}()

}

func endrole() {
	kendynet.Infoln("-----------------------------------------------------")
	kendynet.Infoln("创角总人数:", userNum_, "成功:", createok, "失败:", createfail)
	kendynet.Infoln("创角平均响应时间:", float64(createTime)/float64(num), createTime, num)
	kendynet.Infoln("获取角色列表总人数:", userNum_, "成功:", roleListok, "失败:", roleListfail)
	kendynet.Infoln("获取角色列表平均响应时间:", float64(roleListTime)/float64(num), roleListTime, num)
	kendynet.Infoln("选角总人数:", userNum_, "成功:", selectok, "失败:", selectfail)
	kendynet.Infoln("选角平均响应时间:", float64(selectTime)/float64(num), selectTime, num)
}

func endMove() {
	kendynet.Infoln("-----------------------------------------------------")
	kendynet.Infoln("创角总人数:", userNum_, "成功:", createok, "失败:", createfail)
	kendynet.Infoln("创角平均响应时间:", float64(createTime)/float64(userNum_), createTime, userNum_)
}
